home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / WAIS / ir / irbuild.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-02  |  14.5 KB  |  435 lines

  1. /* WIDE AREA INFORMATION SERVER SOFTWARE:
  2.    No guarantees or restrictions.  See the readme file for the full standard
  3.    disclaimer.
  4.  
  5.    Brewster@think.com
  6. */
  7.  
  8. /*
  9.  * Building an index with a Unix shell interface.
  10.  *
  11.  * -brewster 6/90
  12.  */
  13.  
  14. /* to do:
  15.  *   done: make incremental indexing not index things that are already index
  16.  *   add extra arg -register that will send in description of the server to 
  17.  *           the directory of servers.
  18.  *   done: create a source struct in the .src file
  19.  *   make it continuously index to keep itself uptodate.
  20.  *
  21.  */
  22.  
  23. #include <string.h>
  24. #include <sys/types.h>
  25. #include "irdirent.h"
  26. #include "cutil.h"
  27. #include "futil.h"
  28. #include "irfiles.h"
  29. #include "irtfiles.h"
  30. #include "panic.h"
  31. #include "ircfiles.h"
  32. #include "version.h"
  33. #include "irext.h"
  34.  
  35. #define INDEXER_DATE "Fri Sep 13 1991"
  36.  
  37. /* for reporting errors, in WAIStation it is defined in CRetrievalApp.c */
  38.  
  39. extern boolean indexingForBeta;
  40.  
  41. char *log_file_name = NULL;
  42. FILE *logfile;
  43.  
  44. /* This is the MAIN for building an index.
  45.  */
  46. void
  47. main(argc, argv)
  48. int argc;
  49. char *argv[];
  50. {
  51.   database* db = NULL;
  52.   long argc_copy = argc;
  53.   char **argv_copy = argv;
  54.   char *next_argument;
  55.   char index_filename[1000];
  56.   boolean (*separator_function)();
  57.   void (*header_function)();
  58.   void (*finish_header_function)();
  59.   long (*date_function)();
  60.   boolean adding_to_existing_index = FALSE;
  61.   boolean traverse_directory = FALSE;
  62.   long memory_to_use = -1;
  63.   boolean check_for_text_file = FALSE;
  64.   boolean register_database = FALSE;
  65.   boolean export_database = FALSE;
  66.   char *typename = NULL;  /* this is what the user said */
  67.   char *type = NULL;      /* this is the type stored with the db */
  68.   long start_of_filenames;
  69.   long hashtable_size = 1L<<16;
  70.   long flush_after_n_words = 500000;
  71.   char *command_name;
  72.  
  73.   next_argument = next_arg(&argc, &argv);
  74.   separator_function = NULL; /* initailize to nil */
  75.   header_function = NULL;
  76.   date_function = NULL;
  77.   finish_header_function = NULL;
  78.   type = "TEXT"; /* default to text */
  79.   typename = "Text"; 
  80.  
  81.   command_name = next_argument;
  82.  
  83.   logfile = stderr;
  84.  
  85.   if(0 == argc){ /* no args */
  86.     printf("Usage: %s [-d index_filename]\n", next_argument);
  87.     printf("          [-a] /* adding to an existing index, otherwise it erases the index */\n");
  88.     printf("          [-r] /* recursively index subdirectories */\n");
  89.     printf("          [-mem mbytes] /* number of megabytes to run this in */\n");
  90.     printf("          [-register] /* registers the database with the directory of servers.\n");
  91.     printf("                         This should be done with care. */\n");
  92.     printf("          [-export]   /* uses short dbname and port 210 */\n");
  93.     printf("          [-v] /* print the version of the software */\n");
  94.     printf("          [-t  /* format of the file. if none then each file is a document */\n");
  95.     printf("             text /* simple text files, this is the default */\n");
  96.     printf("           | groliers  /* groliers encyclopedia format */\n");
  97.     printf("           | mail /* unix mail and netnews format */\n");
  98.     printf("           | rmail /* gnu rmail */\n");
  99.     printf("           | mail_or_rmail /* mail or rmail or both */\n");
  100.     printf("           | mail_digest /* standard internet mail digest format */\n");
  101.     printf("           | mh_bboard /* MH bulletin board format */\n");
  102.     printf("           | netnews /* netnews format */\n");
  103.     printf("           | catalog /* Thinking Machines library catalog */\n");
  104.     printf("           | bio /* biology abstract format */\n");
  105.     printf("           | cmapp /* CM applications from Hypercard */\n");
  106.     printf("           | pict /* pict files, only indexes the filename */\n");
  107.     printf("           | gif /* gif files, only indexes the filename */\n");
  108.     printf("           | tiff /* tiff files, only indexes the filename */\n");
  109.     printf("           | jargon /* the jargon file (the hackers dictionary) */\n");
  110.     printf("           | server /* server structures for the dir of servers */\n");
  111.     printf("           | objc /* objective-C .h and .m files */\n");
  112.     printf("           | irg /* internet resource guide */\n");
  113.     printf("           | dash /* entries separated by a row of dashes */\n");
  114.     printf("           | one_line /* each line is a document */\n");
  115.     printf("           | para /* paragraphs separated by blank lines */\n");
  116.     printf("          ] filename filename ...\n");
  117.     exit(0);
  118.   }
  119. #ifdef THINK_C
  120.   strcpy(index_filename, "wais:System Folder:wais-index:index");
  121. #else
  122.   strcpy(index_filename, "index"); /* in the current directory */
  123. #endif /* THINK_C */
  124.   
  125.   if(NULL == (next_argument = next_arg(&argc, &argv))){
  126.     printf("No arguments specified\n");
  127.     exit(0);
  128.   }
  129.   while('-' == next_argument[0]){
  130.     /* then we have an argument to process */
  131.     if((0 == strcmp("-i", next_argument)) || /* -i is for backcompatibility */
  132.        (0 == strcmp("-d", next_argument))){
  133.       if(NULL == (next_argument = next_arg(&argc, &argv))){
  134.     printf("Expected filename for the index\n");
  135.     exit(0);
  136.       }
  137.       strcpy(index_filename, next_argument);
  138.       }
  139.     else if(0 == strcmp("-a", next_argument)){
  140.       adding_to_existing_index = true;
  141.     }
  142.     else if(0 == strcmp("-r", next_argument)){
  143.       traverse_directory = true;
  144.     }
  145.     else if(0 == strcmp("-register", next_argument)){
  146.       register_database = true;
  147.     }
  148.     else if(0 == strcmp("-export", next_argument)){
  149.       export_database = true;
  150.     }
  151.     else if(0 == strcmp("-v", next_argument)){
  152.       printf("%s: %s\n", command_name, VERSION, INDEXER_DATE);
  153.     }
  154.     else if(0 == strcmp("-mem", next_argument)){
  155.       if(NULL == (next_argument = next_arg(&argc, &argv)))
  156.     panic("Expected a number for the amount of memory to use");
  157.       memory_to_use = atol(next_argument);
  158.       if(memory_to_use < 1)
  159.     panic("The -mem argument should not be less than 1");
  160.       if(memory_to_use > 200)
  161.     printf("Warning: The -mem parameter was %ld Mbytes.  That is a large number of mega bytes in current machines\n", memory_to_use);
  162.     }
  163.     else if(0 == strcmp("-cm", next_argument)){
  164.       /* this is an undocumented argument to help use this to
  165.      front end the CM application */
  166.       indexingForBeta = true;
  167.     }
  168.     else if(0 == strcmp("-t", next_argument)){
  169.       /* then we have a specialized file */
  170.       if(NULL == (next_argument = next_arg(&argc, &argv)))
  171.     panic("Expected a file type");
  172.       if(0 == strcmp("groliers", next_argument)){
  173.     typename = next_argument;
  174.     type = "TEXT";
  175.     separator_function = groliers_separator_function;
  176.     header_function = groliers_header_function;
  177.     finish_header_function = groliers_finish_header_function;
  178.       }
  179.       else if(0 == strcmp("objc", next_argument)){
  180.     typename = next_argument;
  181.     type = "TEXT";
  182.     separator_function = wobjc_separator_function;
  183.     header_function = wobjc_header_function;
  184.     finish_header_function = wobjc_finish_header_function;
  185.       }
  186.       else if(0 == strcmp("mail", next_argument)){
  187.     typename = next_argument;
  188.     type = "TEXT";
  189.     separator_function = mail_separator_function;
  190.     header_function = mail_header_function;
  191.     date_function = mail_date_function;
  192.     finish_header_function = mail_finish_header_function;
  193.       }
  194.       else if(0 == strcmp("mail_or_rmail", next_argument)){
  195.     typename = next_argument;
  196.     type = "TEXT";
  197.     separator_function = mail_or_rmail_separator;
  198.     header_function = mail_header_function;
  199.     date_function = mail_date_function;
  200.     finish_header_function = mail_finish_header_function;
  201.       }
  202.       else if(0 == strcmp("mail_digest", next_argument)){
  203.     typename = next_argument;
  204.     type = "TEXT";
  205.     separator_function = mail_digest_separator_function;
  206.      header_function = mail_header_function;
  207.      date_function = mail_date_function;
  208.      finish_header_function = mail_finish_header_function;
  209.       }
  210.       else if(0 == strcmp("mh_bboard", next_argument)){
  211.      typename = next_argument;
  212.      type = "TEXT";
  213.      separator_function = mh_bboard_separator_function;
  214.     header_function = mail_header_function;
  215.     date_function = mail_date_function;
  216.     finish_header_function = mail_finish_header_function;
  217.       }
  218.       else if(0 == strcmp("rmail", next_argument)){
  219.     typename = next_argument;
  220.     type = "TEXT";
  221.     separator_function = rmail_separator_function;
  222.     header_function = mail_header_function;
  223.     date_function = mail_date_function;
  224.     finish_header_function = mail_finish_header_function;
  225.       }
  226.       else if(0 == strcmp("netnews", next_argument)){
  227.     typename = next_argument;
  228.     type = "TEXT";
  229.     separator_function = NULL;
  230.     header_function = mail_header_function;
  231.     date_function = mail_date_function;
  232.     finish_header_function = mail_finish_header_function;
  233.       }
  234.       else if(0 == strcmp("catalog", next_argument)){
  235.     typename = next_argument;
  236.     type = "TEXT";
  237.     separator_function = catalog_separator_function;
  238.     header_function = catalog_header_function;
  239.     finish_header_function = catalog_finish_header_function;
  240.       }
  241.       else if(0 == strcmp("bio", next_argument)){
  242.     typename = next_argument;
  243.     type = "TEXT";
  244.     separator_function = bio_separator_function;
  245.     header_function = bio_header_function;
  246.     finish_header_function = bio_finish_header_function;
  247.       }
  248.       else if(0 == strcmp("cmapp", next_argument)){
  249.     typename = next_argument;
  250.     type = "TEXT";    
  251.     separator_function = cmapp_separator_function;
  252.     header_function = cmapp_header_function;
  253.     finish_header_function = cmapp_finish_header_function;
  254.       }
  255.       else if(0 == strcmp("pict", next_argument)){
  256.     typename = next_argument;
  257.     type = "PICT";    
  258.       }
  259.       else if(0 == strcmp("gif", next_argument)){
  260.     typename = next_argument;
  261.     type = "GIF";    
  262.       }
  263.       else if(0 == strcmp("tiff", next_argument)){
  264.     typename = next_argument;
  265.     type = "TIFF";    
  266.       }
  267.       else if(0 == strcmp("jargon", next_argument)){
  268.     typename = next_argument;
  269.     type = "TEXT";
  270.     separator_function = jargon_separator_function;
  271.     header_function = jargon_header_function;
  272.     finish_header_function = jargon_finish_header_function;
  273.       }
  274.       else if(0 == strcmp("server", next_argument)){
  275.     typename = next_argument;
  276.     type = "WSRC";
  277.       }
  278.       else if(0 == strcmp("text", next_argument)){
  279.     type = "TEXT";
  280.     typename = next_argument;
  281.     check_for_text_file = true;
  282.       }
  283.       else if(0 == strcmp("irg", next_argument)){
  284.     typename = next_argument;
  285.     type = "TEXT";
  286.     separator_function = irg_separator_function;
  287.     header_function = irg_header_function;
  288.     finish_header_function = irg_finish_header_function;
  289.       }
  290.       /* dash-separated items , Intro to Algorithms buglist, etc */
  291.       else if(0 == strcmp("dash", next_argument)){
  292.     type = "TEXT";
  293.     typename = next_argument;
  294.     separator_function = dash_separator_function;
  295.     header_function = dash_header_function;
  296.     finish_header_function = dash_finish_header_function;
  297.       }
  298.       /* one_line-separated items */
  299.       else if(0 == strcmp("one_line", next_argument)){
  300.     type = "TEXT";
  301.     typename = next_argument;
  302.     separator_function = one_line_separator_function;
  303.     header_function = one_line_header_function;
  304.     finish_header_function = one_line_finish_header_function;
  305.       }
  306.       /* blank line-separated items (paragraphs) */
  307.       else if(0 == strcmp("para", next_argument)){
  308.     type = "TEXT";
  309.     typename = next_argument;
  310.     separator_function = para_separator_function;
  311.     header_function = para_header_function;
  312.     finish_header_function = para_finish_header_function;
  313.       }
  314.       /* seeker items */
  315.       else if(0 == strcmp("seeker", next_argument)){
  316.     type = "TEXT";
  317.     typename = next_argument;
  318.     separator_function = seeker_separator_function;
  319.     header_function = seeker_header_function;
  320.     finish_header_function = seeker_finish_header_function;
  321.       }
  322.       /* rlin items */
  323.       else if(0 == strcmp("rlin", next_argument)){
  324.     type = "TEXT";
  325.     typename = next_argument;
  326.     separator_function = rlin_separator_function;
  327.     header_function = rlin_header_function;
  328.     finish_header_function = rlin_finish_header_function;
  329.       }
  330.       else{
  331.     panic("Don't recognize the '%s' type", next_argument);
  332.       }
  333.     }
  334.     else{
  335.       panic("Don't recognize the '%s' option", next_argument);
  336.     }
  337.     if(NULL == (next_argument = next_arg(&argc, &argv))){
  338.       printf("No files specified\n");
  339.       exit(0);
  340.     }
  341.   }
  342.   start_of_filenames = argc_copy - argc - 1;
  343.  
  344.   waislog(WLOG_MEDIUM, WLOG_INDEX, "Starting to build");
  345.  
  346.   if(true == adding_to_existing_index){
  347.     db = openDatabase(index_filename, false, false);
  348.     if (db == NULL){ /* does not exist, create one */
  349.       db = openDatabase(index_filename, true, false);
  350.       if (db == NULL)
  351.     panic("unable to open the database");
  352.     }
  353.   }
  354.   else{
  355.     db = openDatabase(index_filename, true, false);
  356.     if (db == NULL)
  357.       panic("unable to open the database");
  358.   }
  359.   { /* set up the memory hashtable */
  360.  
  361.     if(memory_to_use < 0){ /* default */
  362.       /* do nothing */
  363.     }
  364.     else if(memory_to_use <= 2){
  365.       hashtable_size = 1L<<16;
  366.       flush_after_n_words = 100000;
  367.     }
  368.     else if(memory_to_use <= 5){
  369.       hashtable_size = 1L<<16;
  370.       flush_after_n_words = 200000;
  371.     }
  372.     else if(memory_to_use <= 10){
  373.       /* shown to take about 6MB on a sun4, when it is dict limited */
  374.       hashtable_size = 1L<<16;
  375.       flush_after_n_words = 500000;
  376.     }
  377.     else if(memory_to_use <= 20){
  378.       hashtable_size = 1L<<17;
  379.       flush_after_n_words = 1200000;
  380.     }
  381.     else{ /* over 20 Mbytes */
  382.       hashtable_size = 1L<<18;
  383.       flush_after_n_words = 4000000;
  384.     }
  385.     init_add_word(db, hashtable_size, flush_after_n_words);
  386.   }
  387.   while(NULL != next_argument){ /* the first filename is in next_argument already */
  388.     if(directoryp(next_argument)){
  389.        if(traverse_directory){
  390.      index_directory(next_argument,
  391.              separator_function,
  392.              header_function,
  393.              date_function,
  394.              finish_header_function,
  395.              type, db,
  396.              check_for_text_file,
  397.              adding_to_existing_index);
  398.        }
  399.      }
  400.     else{            /* not a directory */
  401.       waislog(WLOG_MEDIUM, WLOG_INDEX, 
  402.           "Indexing file: %s", next_argument);
  403.       index_text_file(next_argument,
  404.               separator_function,
  405.               header_function,
  406.               date_function,
  407.               finish_header_function,
  408.               type, db, 
  409.               check_for_text_file, adding_to_existing_index);
  410.     }
  411.     next_argument = next_arg(&argc, &argv);
  412.   }
  413.   finished_add_word(db);
  414.   {
  415.     char filename[MAX_FILENAME_LEN + 1];
  416.     if(!probe_file(source_filename(filename, db))){
  417.       char database_name[MAX_FILENAME_LEN];
  418.       write_src_structure(source_filename(filename, db),
  419.               export_database?pathname_name(index_filename):
  420.                       truename(index_filename, database_name),
  421.               typename,
  422.               &argv_copy[start_of_filenames],
  423.               argc_copy - start_of_filenames,
  424.               export_database,
  425.               210L);
  426.     }
  427.     /* write out a description of the server if appropriate */
  428.     if(register_database){
  429.       register_src_structure(source_filename(filename, db));
  430.     }
  431.   }
  432.   closeDatabase(db);
  433.   exit(0);
  434. }
  435.